package com.tony.blog.server.service.web.impl;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.base.Joiner;
import com.google.common.collect.Maps;
import com.tony.blog.api.utils.BlogMsg;
import com.tony.blog.api.utils.Constant;
import com.tony.blog.api.utils.PageUtil;
import com.tony.blog.api.utils.QueryUtil;
import com.tony.blog.model.entity.BlogEntity;
import com.tony.blog.model.entity.SysUserEntity;
import com.tony.blog.model.mapper.*;
import com.tony.blog.server.service.web.BlogService;
import com.tony.blog.server.shiro.ShiroUtil;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.util.CollectionUtils;
import org.apache.tomcat.util.bcel.Const;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.core.env.Environment;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * Created with IntelliJ IDEA.
 *
 * @Title: BlogServiceImpl
 * @Auther: 皮蛋布丁
 * @Date: 2021/08/15/19:05
 * @Description:
 */
@Service("blogService")
public class BlogServiceImpl extends ServiceImpl<BlogMapper, BlogEntity> implements BlogService {

    private static final Logger log = LoggerFactory.getLogger(BlogServiceImpl.class);

    @Autowired
    private Environment env;
    @Autowired
    private BlogImageMapper blogImageMapper;
    @Autowired
    private CollectMapper collectMapper;
    @Autowired
    private PraiseMapper praiseMapper;
    @Autowired
    private ConcernMapper concernMapper;
    @Autowired
    private CommentMapper commentMapper;
    @Autowired
    private ApplicationEventPublisher publisher;

    /**
    * @Description: queryPage 获取首页数据列表信息(向下滚动分页)
    * @Param: [paramMap(searchType==1表示找博客；searchType==0表示找人；searchText表示待搜索的内容)]
    * @return: com.tony.blog.api.utils.PageUtil
    * @Author: 皮蛋布丁
    * @Date: 2021/8/15 19:08
    */
    @Override
    public PageUtil queryPage(Map<String, Object> paramMap) {
        //构造pageNo pageSize
        IPage<BlogEntity> page = new QueryUtil<BlogEntity>().getQueryPage(paramMap);
        //获取首页博文列表
        List<BlogEntity> list = baseMapper.pageCenterBlog(page,paramMap);
        //处理每篇博文额外的数据
        this.commonManageBlog(list);
        page.setRecords(list);
        return new PageUtil(page);
    }

    /**
    * @Description: commonManageBlog 通用处理博文列表数据
    * @Param: [list]
    * @return: java.util.List<com.tony.blog.model.entity.BlogEntity>
    * @Author: 皮蛋布丁
    * @Date: 2021/8/15 19:13
    */
    public List<BlogEntity> commonManageBlog(List<BlogEntity> list) {
        if (list != null && !list.isEmpty()) {
            list.forEach(this::commonManageSingleBlog);
        }
        return list;
    }

    /**
    * @Description: commonManageSingleBlog 单独处理每条微博的额外的数据信息：微博图片、博主信息、是否已点赞/收藏/转发等信息
    * @Param: [blogEntity]
    * @return: void
    * @Author: 皮蛋布丁
    * @Date: 2021/8/15 19:16
    */
    @Override
    public void commonManageSingleBlog(BlogEntity blogEntity) {
        try {
            Map<String,Object> otherMap = Maps.newHashMap();
            //转发-2
            if (2 == blogEntity.getType()) {
                //根据id获取博文
                BlogEntity fromBlog = baseMapper.selectByPK(blogEntity.getBlogId());
                if (null == fromBlog) {
                    fromBlog = new BlogEntity();
                    fromBlog.setContent(env.getProperty("common.blog.delete.content"));
                    fromBlog.setNickName(env.getProperty("common.blog.delete.nickName"));
                    fromBlog.setCreateTime(new Date());
                    fromBlog.setHeaderImg(env.getProperty("common.user.img.blog.delete.default"));
                } else {
                    //获取博文图片数组
//                    List<String> blogImgUrls = blogImageMapper.selectByBlogId(blogEntity.getBlogId(),env.getProperty("common.user.img.root.url"));
                    List<String> blogImgUrls = blogImageMapper.selectByBlogId2(blogEntity.getBlogId());
                    List<String> imgUrls = new ArrayList<>();
                    for (String url : blogImgUrls) {
                        if (url.startsWith("headPortrait/") || url.startsWith(
                                "miniBlog/")) {
                            imgUrls.add(env.getProperty("common.user.img.root.url") + url);
                        } else {
                            imgUrls.add(env.getProperty("common.file.upload.root.url") + url);
                        }
                    }
                    fromBlog.setImgUrls(imgUrls);
                }
                //设置用户头像
                if (StringUtils.isBlank(fromBlog.getHeaderImg())) {
                    fromBlog.setHeaderImg(env.getProperty("common.user.img.default"));
                }
                if (fromBlog.getHeaderImg().startsWith("headPortrait") || fromBlog.getHeaderImg().startsWith(
                        "miniBlog")) {
                    fromBlog.setHeaderImg(env.getProperty("common.user.img.root.url")+fromBlog.getHeaderImg());
                } else {
                    fromBlog.setHeaderImg(env.getProperty("common.file.access.root.url")+fromBlog.getHeaderImg());
                }
                otherMap.put("fromBlog",fromBlog);
            } else {
                List<String> blogImgUrls = blogImageMapper.selectByBlogId2(blogEntity.getId());
                List<String> imgList = new ArrayList<>();
                for (String url : blogImgUrls) {
                    if (url.startsWith("headPortrait/") || url.startsWith(
                            "miniBlog/")) {
                        imgList.add(env.getProperty("common.user.img.root.url") + url);
                    } else {
                        imgList.add(env.getProperty("common.file.upload.root.url") + url);
                    }
                }
                blogEntity.setImgUrls(imgList);
            }
            //是否：已收藏、已点赞、评论总数、已转发、已关注 - 架构3.0存Redis
            try {
                SysUserEntity entity = ShiroUtil.getUserEntity();
                if (null != entity) {
                    otherMap.put("hasCollect",collectMapper.countByUBlogId(blogEntity.getId(),entity.getUserId()) > 0 ?
                            1 : 0);
                    otherMap.put("hasPraise",praiseMapper.countByUBlogId(blogEntity.getId(),entity.getUserId()) > 0 ? 1 : 0);
                    otherMap.put("hasForward",baseMapper.countByForwardBlog(entity.getUserId(),blogEntity.getId()) > 0 ? 1 :0);
                    otherMap.put("hasConcern",concernMapper.countByConcernBeId(entity.getUserId().intValue(),blogEntity.getUserId().intValue()) > 0 ? 1 :0);
                }
            } catch (Exception e) {}
            otherMap.put("commentTotal",commentMapper.countByBlogId(blogEntity.getId()));
            blogEntity.setOtherMap(otherMap);

            //设置用户头像
            if (StringUtils.isBlank(blogEntity.getHeaderImg())) {
                blogEntity.setHeaderImg(env.getProperty("common.user.img.default"));
            }
            if (blogEntity.getHeaderImg().startsWith("headPortrait") || blogEntity.getHeaderImg().startsWith(
                    "miniBlog")) {
                blogEntity.setHeaderImg(env.getProperty("common.user.img.root.url")+blogEntity.getHeaderImg());
            } else {
                blogEntity.setHeaderImg(env.getProperty("common.file.access.root.url")+blogEntity.getHeaderImg());
            }
        } catch (Exception e) {
            log.error("处理单条博文信息发生异常：",e);
        }
    }

    /**
    * @Description: countByForwardBlog 获取转发博文数量
    * @Param: [userId, blogId]
    * @return: java.lang.Integer
    * @Author: 皮蛋布丁
    * @Date: 2021/9/10 14:28
    */
    @Override
    public Integer countByForwardBlog(Long userId, Integer blogId) {
        return baseMapper.countByForwardBlog(userId,blogId);
    }

    /**
    * @Description: queryPagePraises 我点赞的博文(分页)
    * @Param: [params]
    * @return: com.tony.blog.api.utils.PageUtil
    * @Author: 皮蛋布丁
    * @Date: 2021/9/10 16:36
    */
    @Override
    public PageUtil queryPagePraises(Map<String, Object> params) {
        //构造pageNo pageSize
        IPage<BlogEntity> page = new QueryUtil<BlogEntity>().getQueryPage(params);
        //获取首页博文列表
        List<BlogEntity> list = baseMapper.selectPraiseBlogByUId(page,params);
        commonManageBlog(list); //通用处理博文数据列表
        page.setRecords(list);
        return new PageUtil(page);
    }

    /**
    * @Description: queryPageCollects 获取我收藏的博文列表(分页)
    * @Param: [paramMap]
    * @return: com.tony.blog.api.utils.PageUtil
    * @Author: 皮蛋布丁
    * @Date: 2021/9/16 10:12
    */
    @Override
    public PageUtil queryPageCollects(Map<String, Object> paramMap) {
        //构造pageNo pageSize
        IPage<BlogEntity> page = new QueryUtil<BlogEntity>().getQueryPage(paramMap);

        //获取首页博文列表
        List<BlogEntity> list = baseMapper.selectCollectBlogByUId(page,paramMap);
        commonManageBlog(list);

        page.setRecords(list);
        return new PageUtil(page);
    }

    /**
    * @Description: queryPageAdmin 获取博文列表(分页、模糊)
    * @Param: [params]
    * @return: com.tony.blog.api.utils.PageUtil
    * @Author: 皮蛋布丁
    * @Date: 2021/9/29 10:16
    */
    @Override
    public PageUtil queryPageAdmin(Map<String, Object> params) {
        IPage<BlogEntity> page = new QueryUtil<BlogEntity>().getQueryPage(params);

        List<BlogEntity> list = baseMapper.pageBlogAdmin(page,params);
        if (!CollectionUtils.isEmpty(list)) {
            list.forEach(b -> {
                b.setCommentTotal(commentMapper.countByBlogId(b.getId()));  //评论数
                b.setPraiseTotal(praiseMapper.countByUBlogId(b.getId(),null));  //点赞数
                b.setCollectTotal(collectMapper.countByUBlogId(b.getId(),null));    //收藏数
            });
        }
        page.setRecords(list);
        return new PageUtil(page);
    }

    /**
    * @Description: deleteEntity 根据id删除博文
    * @Param: [ids]
    * @return: java.lang.Integer
    * @Author: 皮蛋布丁
    * @Date: 2021/9/29 11:17
    */
    @Override
    public Integer deleteEntity(List<Integer> ids) {
        if (!CollectionUtils.isEmpty(ids)) {
            String idStr = Joiner.on(",").join(ids);
            baseMapper.deletes(idStr);
            ids.forEach(id -> {
                //region 方式一：事件启动模型解耦服务
                publisher.publishEvent(new BlogMsg(this,id,Constant.BlogIndexMsg.Delete.getType()));
                //endrediong

                //region 方式二：内存队列解耦服务
                Constant.BLOG_Queue.add(new BlogMsg(this,id,
                        Constant.BlogIndexMsg.Delete.getType()));
                //endregion
            });
        }

        return ids.size();
    }

    /**
    * @Description: activeEntity 根据id批量屏蔽/恢复博文
    * @Param: [ids]
    * @return: java.lang.Integer
    * @Author: 皮蛋布丁
    * @Date: 2021/9/29 11:45
    */
    @Override
    public Integer activeEntity(List<Integer> ids) {
        if (ids != null && !ids.isEmpty()) {
            String idStr = Joiner.on(",").join(ids);
            baseMapper.active(idStr);

            //事件启动模型解耦服务
            this.actionOrUnActiveIndex(idStr);
        }
        return ids.size();
    }

    /**
    * @Description: actionOrUnActiveIndex 屏蔽掉的博文需要移除磁盘中的索引；恢复回来的博文需要重新添加回索引
    * @Param: [ids]
    * @return: void
    * @Author: 皮蛋布丁
    * @Date: 2021/9/29 14:11
    */
    @Async
    public void actionOrUnActiveIndex(String ids) {
        if (StringUtils.isNotBlank(ids)) {
            List<BlogEntity> list = baseMapper.selectByIds(ids);
            if (!CollectionUtils.isEmpty(list)) {
                list.forEach(blog -> {
                    try {
                        //region 方式一：事件启动模型解耦服务
                        if (Objects.equals(1,blog.getIsActive())) {
                            publisher.publishEvent(new BlogMsg(this, blog.getId(),
                                    Constant.BlogIndexMsg.Active.getType()));
                        } else {
                            publisher.publishEvent(new BlogMsg(this,blog.getId(),
                                    Constant.BlogIndexMsg.UnActive.getType()));
                        }
                        //endregion

                        //region 方式二：内存队列解耦服务
                        if (Objects.equals(1,blog.getIsActive())) {
                            Constant.BLOG_Queue.add(new BlogMsg(this,blog.getId(),
                                    Constant.BlogIndexMsg.Active.getType()));
                        } else {
                            Constant.BLOG_Queue.add(new BlogMsg(this,blog.getId(),
                                    Constant.BlogIndexMsg.UnActive.getType()));
                        }
                        //endregion

                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                });
            }
        }
    }

}
